#include "jpg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>

#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <linux/fb.h>
#include <linux/un.h>
#include <linux/input.h>

#include <arpa/inet.h>
#include <netinet/in.h>

//全局变量
//音量调节    madplay -a  volume ./mp3/*.mp3
int volume = -25;

//初始化LCD显示屏
char *init_lcd(struct fb_var_screeninfo *vinfo)
{
	int lcd = open("/dev/fb0", O_RDWR);

	ioctl(lcd, FBIOGET_VSCREENINFO, vinfo);
	int bpp = vinfo->bits_per_pixel;
	int screensize = vinfo->xres * vinfo->yres * bpp/8;

	char *fbmem = mmap(NULL, screensize, PROT_READ|PROT_WRITE,
			   MAP_SHARED, lcd, 0);
	if(fbmem == MAP_FAILED)
	{
		perror("映射显存失败");
		exit(0);
	}
	return fbmem;
}

/*
1231 1231 345 345 

111 -5  333 1 135 5 

//天空之城
67878107336568534348388874477
*/

//返回手指对屏幕操作序号
int re_num(int x , int y)
{
	//琴键操作
	int x_num ;
	if(( 50 <= y && y <= 330))
	{
		//琴键序号
		return x_num = (x-10)/65 + 1;
	}
	
	//退出操作
	else if((750 < x && x <= 800)&&( 0 <= y && y <= 50))
	{
		return 13;
	}

	//减小音量操作
	else if(( 655 < x && x <= 705)&&( 0<= y && y <= 45))
	{
		return 14;
	}
	//增大音量操作
	else if(( 585 < x && x <= 635 )&&( 0<= y && y <= 45))
	{
		return 15;
	}
    
    //无效操作位置	
    else
	{
		return -1;
	}
		
}


//手指对功能的操作
int touch(int tp)
{
	struct input_event  buf;
	
	// 准备好 LCD 设备
	struct fb_var_screeninfo vinfo;
	bzero(&vinfo, sizeof(vinfo));
	char *fbmem = init_lcd(&vinfo);
	//int flags = -2;
	int x = -1,y = -1;
	//bool xdone = false, ydone = true;
	int new = -1 ,old = -1;
	while(1)
	{
		bzero(&buf,sizeof(buf));
		read(tp,&buf,sizeof(buf));
			
		if(buf.type == EV_ABS && buf.code == ABS_X)
		{	
		     x = buf.value;
		}
	    if(buf.type == EV_ABS && buf.code == ABS_Y)
		{
		     y = buf.value;
		}
	//	printf("(%d , %d)\n",x,y);
		
		//如果按击的是琴键
		if(buf.type == EV_ABS && x != -1 && y != -1)
		{
		     old =  new;
			 //获取琴键序号 
             printf("old_touch    : %d\n",old);
		     printf("\n\n");
		        
			 new = re_num(x,y);
			 printf("new_touch    : %d\n",new); 		 
			 if(1 <= new <= 12)
			 {
			    
			   if(old == new)
			   {
				   continue;
			   }
			   //按击琴键，显示按下状态图片
			   else 
			   {
	    	       display("./jpg/key_on.jpg", fbmem , &vinfo , 10+(new-1)*65 , 50 );
			       printf("%琴键序号为：d\n",new);	 

                   //返回琴键序号				   
				   return new; 
			   }   
		     }
 		   
		}
		
	
		//手指按下
		if(buf.type == EV_KEY &&
		   buf.code == BTN_TOUCH &&
		   buf.value > 0)
		   {	    
             ;
		   }
		 //手指离开屏幕
		if(buf.type == EV_KEY &&
		   buf.code == BTN_TOUCH &&
		   buf.value == 0)
		   {  	    
     	
     			//手指离开琴键，显示初始状态图片
			    int i = 0;
	         	for(i ; i < 12 ; i++)
	            {
	                display("./jpg/key_off.jpg", fbmem , &vinfo , 10+i*65 , 50 );
	            }
				
			    return -2;		
		   } 		   		   
       }
	   
	   //返回非琴键选项
	   if(x != -1 && y != -1)
	   {
		   int renum;
		   return renum = re_num(x,y);
		   
		   printf("非琴键序号：%d",renum);
	   }
	   

}


//子线程负责播放琴声
void *routine(void *x)
{
    char paino_num[100] = {0};
    bzero(paino_num,100);
    snprintf(paino_num ,100,"madplay -a %d ./mp3/d%d.mp3",volume,x);
    system(paino_num);		
}

//负责播放退场音乐
void *routine_exit(void *arg)
{
	system("madplay -a -25 ./mp3/SeeYouAgain.mp3");
}

int main(int argc , char **argv)
{
	// 准备好 LCD 设备
	struct fb_var_screeninfo vinfo;
	bzero(&vinfo, sizeof(vinfo));
	char *fbmem = init_lcd(&vinfo);
	
	
	//显示主页面
    display("./jpg/background.jpg", fbmem , &vinfo , 0 , 0 );
	display("./jpg/bar.jpg", fbmem , &vinfo , 0 , 0 );
	display("./jpg/logo.jpg", fbmem , &vinfo , 220 , 410 );
	display("./jpg/exit.jpg", fbmem , &vinfo , 760, 8 );
	display("./jpg/volume.jpg", fbmem , &vinfo , 500 , 1 );
	display("./jpg/billy.jpg", fbmem , &vinfo , 655 , 432 );
	
	//显示12个琴键
	int i = 0;
	for(i ; i < 12 ; i++)
	{
	   display("./jpg/key_off.jpg", fbmem , &vinfo , 10+i*65 , 50 );
	}
	
	
	
	//打开触摸屏文件
	int tp = open("/dev/input/event0",O_RDONLY);
	
	
	//old,new记录上个和当前琴键序号
    int old = -1,new = -1;	
	while(1)
	{
		old = new;	
		
		printf("old    : %d\n",old);
		new = touch(tp);
		
		printf("\n\n");
		printf("new    : %d\n",new);
		
		//手指离开 重新复位琴键序号
		if( new == -2)
		{
			new = -1;
			old = -1;
			continue;
		}
		
		//退出程序，播放音乐
		if(new == 13)
		{
		   system("killall -9 madplay");
		   display("./jpg/background_exit.jpg", fbmem , &vinfo , 0 , 0 );
		   pthread_t tid;
		   pthread_create(&tid,NULL,routine_exit,NULL); 
		   sleep(5);
		   system("killall -9 madplay");
		   bzero(fbmem, 800*480* 4);
		   exit(1);
		}
		
		//减小音量操作
		if(new == 14)
		{
			if(volume > -50)
			{
				printf("减小音量，当前音量：%d\n",volume);
				volume -= 5;
			}
			else if( volume == -50)
			{
				printf("音量已最小\n");
			}
		}
		
		//增大音量操作
	    if(new == 15)
		{
			if(volume < 0)
			{
				 printf("增大音量，当前音量：%d\n",volume);
				 volume += 5;
		    }
			else if( volume == 0)
			{
				 printf("音量已最大\n");
			}
		}
		if(new == -1)
		{
			continue;
		}


        //返回为琴键序号
		if(1 <= new <= 12)
		{
            //判断琴键是否改变
		    if(new == old)
		    { 
			    continue;
		    }
			else
			{
			   //终止前一个琴声
               system("killall -9 madplay");
	           pthread_t tid;
		
		       //播放新的琴声
               pthread_create(&tid,NULL,routine,(void *)new); 
			   
			   //第一次直接跳过
			   if(old == -1)
			   {
				   continue;
			   } 
			   //将前一个琴键弹起
			   display("./jpg/key_off.jpg", fbmem , &vinfo , 10+(old-1)*65, 50 );	
			   
			}
				
		}		  
		
	}
	return 0;
	
}